#include "SSLBaseService.h"

CSSLBaseService::CSSLBaseService(){
	WSAStartup(MAKEWORD(1,1), &WSAData);

	SSL_load_error_strings();
	ERR_load_BIO_strings();
	OpenSSL_add_all_algorithms();
	SSL_library_init();

	m_ctx = new SSL_CTX;
}

CSSLBaseService::~CSSLBaseService(){
	if(m_ctx)
		delete m_ctx;
	BIO_free_all(m_bio);
	WSACleanup();
}

bool CSSLBaseService::initialize(){
	m_meth = SSLv23_client_method();
	m_ctx = SSL_CTX_new(m_meth);
    if (!m_ctx)
        return false;

	if(! SSL_CTX_load_verify_locations(m_ctx, G_User.m_Cacrt, NULL))
    {
        return false;
    }
	return true;
}

void CSSLBaseService::run(){
	start();
}

void CSSLBaseService::execute(){
	Connect();
	for(;;){
		
	}
}

bool CSSLBaseService::Connect(){
	m_bio = BIO_new_ssl_connect(m_ctx);
	if(m_bio == NULL){
		return false;
	}
	BIO_get_ssl(m_bio, &m_ssl);
	SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY);

	hostent * phostent = gethostbyname(G_User.m_DSDNS);
	char * ip;
	ip = inet_ntoa(*(struct in_addr*)phostent->h_addr_list[0]);

	string host = ip;
	host += ":";
	host += G_User.m_DSPort;

	BIO_set_conn_hostname(m_bio, (char *)(host.c_str()));
	if(BIO_do_connect(m_bio) <= 0){
        return false;
    }
	if(SSL_get_verify_result(m_ssl) != X509_V_OK)
    {
        return false;
    }
    return true;
}

int CSSLBaseService::Send(char * buf, int len){
	int ret = 0;
	ret = BIO_write(m_bio, buf, len);
	return ret;
}

int CSSLBaseService::Receive(char * buf, int len){
	int ret = 0;
	ret = BIO_read(m_bio, (void *)buf, len);
	return ret;
}
